查看原文
其他

如果火锅只能吃三样......

zuobangbang Python爱好者社区 2019-04-07

作者:zuobangbang
微信公众号:zuobangbang


昨天刷过微博的筒子们应该都看到了这样一条热搜:如果火锅只能点三样,话说我能都要吗。但如果真的要选,我应该会选虾滑,油面筋,嫩牛肉~~~想一想口水都会掉下来呢。

在大家心中的TOP3是谁呢???带着这个问题接着往下看把~


今天要爬的是图院长发的一条微博,截至上午9:14,一共有4.6万条评论。微博作为反爬界的大佬,是不会要你轻易爬取到它的信息的。(曾经尝试过用微博API,但是密钥的申请过于复杂,直接放弃了)网页不好爬,那我们就爬手机端啊。Fiddler的下载安装请参考用Fiddler+MongoDB抓取猫眼APP短评


微博评论采用的是异步加载的方式,不停往下翻页,在Fiddler不断的有数据加载进来;

这个页面的URL非常的复杂(https://api.weibo.cn/2/comments/build_comments?flow=0&gsid=_2A2528V-DDeRxGeRM7loV9ifJyDuIHXVTp9RLrDV6PUJbkdAKLVf5kWpNU807bwxYkTUD9lwoQyaK4ajn_4FoWbka&wm=3333_2001&i=2a48abc&b=0&from=108B193010&c=iphone&networktype=wifi&v_p=69&skin=default&v_f=1&s=b1c8ec8f&lang=zh_CN&sflag=1&ua=iPhone9,1__weibo__8.11.1__iphone__os11.2.5&ft=11&aid=01AkR6c52cGZnAKXiIy1qC93kKA4LStXUv_uVymvDYrbPVZaw.&is_append_blogs=1&mid=4308928831894875&fid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D3&uicode=10000002&count=20&trim_level=1&moduleID=feed&max_id=141992686212489&is_show_bulletin=2&fetch_level=0&_status_id=4308928831894875&max_id_type=0&id=4308928831894875&luicode=10000003&featurecode=10000085&is_mix=1&page=0&lfid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D3&lcardid=seqid%3A23443762%7Ctype%3A1%7Ct%3A31%7Cpos%3A1-2-0%7Cq%3A%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%7Cext%3A%26cate%3D306%26mid%3D4308928831894875%26qtime%3D1542854023%26&rid=0_0_0_2667276034987506065_0_0&cum=DF372ED1)。对比了两页评论URL的参数,发现它的page均为0,只有下面这几个参数是不同的。

在这个URL返回的JSON里,笔者发现了这个:在URL和JSON里,都出现了max_id。前一面JSON出现的max_id在下一面的URL里。

因此有了一个大胆的猜想,参数(max_id)就是充当了一个翻页的作用,第一面的max_id会出现在第二面的URL里。

整个程序确实跑起来了,但是它会不定时的返回一个取值为0 的max_id;程序就会自动结束。所以,我加入了一个控制次数的变量zero=5;max_id取0在五次内,程序都不会结束。

while zero:
   url ='https://api.weibo.cn/2/comments/build_comments?flow=1&gsid=_2A2528V-DDeRxGeRM7loV9ifJyDuIHXVTp9RLrDV6PUJbkdAKLVf5kWpNU807bwxYkTUD9lwoQyaK4ajn_4FoWbka&wm=3333_2001&i=2a48abc&b=0&from=108B193010&c=iphone&networktype=wifi&v_p=69&skin=default&v_f=1&s=b1c8ec8f&lang=zh_CN&sflag=1&ua=iPhone9,1__weibo__8.11.1__iphone__os11.2.5&ft=11&aid=01AkR6c52cGZnAKXiIy1qC93kKA4LStXUv_uVymvDYrbPVZaw.&is_append_blogs=1&mid=4308928831894875&fid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&uicode=10000002&count=20&trim_level=1&moduleID=feed&max_id={}&is_show_bulletin=2&fetch_level=0&_status_id=4308928831894875&max_id_type=0&id=4308928831894875&luicode=10000003&featurecode=10000085&is_mix=1&page=0&lfid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&lcardid=seqid%3A870460522%7Ctype%3A1%7Ct%3A1%7Cpos%3A1-2-0%7Cq%3A%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%7Cext%3A%26cate%3D306%26mid%3D4308928831894875%26qtime%3D1542865414%26&rid=0_0_0_2669675512959047934_0_0&cum=6DD80FF3'.format(max_id)
   try:
       max_id,num=get_inf(url)
   except Exception as e:
       print(e)
       time.sleep(30)
       max_id,num=get_inf(url)
   if not max_id:
       zero=zero-1
       time.sleep(60)

程序跑起来后发现,下面这段程序出了一个很大的逻辑问题。当max_id为0时,在开始下一次循环时,max_id仍为0,会让程序自动从当前时间点的最新评论开始爬。这段程序我是昨天下午快三点跑的,仔细看下图会看到当max_id为0,它的下一次循环时间从14:37回到了14:51,这意味着整段程序一直在对那几千条评论重复抓取。

所以我在上面那段程序的基础上加入了一个变量max,在max_id更新前将它先保存下来,如果max_id变为0,把max的值赋予给max_id。

while zero:
   url ='https://api.weibo.cn/2/comments/build_comments?flow=1&gsid=_2A2528V-DDeRxGeRM7loV9ifJyDuIHXVTp9RLrDV6PUJbkdAKLVf5kWpNU807bwxYkTUD9lwoQyaK4ajn_4FoWbka&wm=3333_2001&i=2a48abc&b=0&from=108B193010&c=iphone&networktype=wifi&v_p=69&skin=default&v_f=1&s=b1c8ec8f&lang=zh_CN&sflag=1&ua=iPhone9,1__weibo__8.11.1__iphone__os11.2.5&ft=11&aid=01AkR6c52cGZnAKXiIy1qC93kKA4LStXUv_uVymvDYrbPVZaw.&is_append_blogs=1&mid=4308928831894875&fid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&uicode=10000002&count=20&trim_level=1&moduleID=feed&max_id={}&is_show_bulletin=2&fetch_level=0&_status_id=4308928831894875&max_id_type=0&id=4308928831894875&luicode=10000003&featurecode=10000085&is_mix=1&page=0&lfid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&lcardid=seqid%3A870460522%7Ctype%3A1%7Ct%3A1%7Cpos%3A1-2-0%7Cq%3A%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%7Cext%3A%26cate%3D306%26mid%3D4308928831894875%26qtime%3D1542865414%26&rid=0_0_0_2669675512959047934_0_0&cum=6DD80FF3'.format(max_id)
   max = max_id
   try:
       max_id,num=get_inf(url)
   except Exception as e:
       print(e)
       time.sleep(30)
       max_id,num=get_inf(url)
   if not max_id:
       max_id=max
       zero=zero-1
       time.sleep(60)

加入这样一个变量后,整段程序变得正常起来,从下图可以看到,当max_id变为0时,时间从13:35:35变成了13:35:10。

这段代码是昨天下午三点多跑的,一共爬了差不多两万条评论。但是这个话题太火了,一直在热搜榜上,所以今早重新爬了一次,一共爬了41897条评论。

整个爬虫代码如下:

import random
from pymongo import MongoClient
import requests
import time
collection=MongoClient('localhost',27017)
collection=collection['weibo']['weibo']
user=['Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0',
     'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36',
     'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36']
headers={
'Host': 'api.weibo.cn',
'User-Agent':random.choice(user),
'Cookie':'ALF=1544929289; _T_WM=39e20928a39c3b92a9cdd8d71f3e2550; WEIBOCN_FROM=1110006030',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'}

def get_inf(url):
   html = requests.get(url, headers=headers).json()
   max_id = html['max_id']
   print(max_id)
   n=0
   print( html['root_comments'])
   for i in html['root_comments']:
       inf = {}
       inf['text'] = i['text']
       inf['time'] = i['created_at']
       inf['disable_reply'] = i['disable_reply']
       inf['liked']=i['like_counts']
       inf['nick'] = i['user']['name']
       #inf['class'] = i['user']['class']
       inf['sex'] = i['user']['gender']
       inf['city'] = i['user']['city']
       inf['pro'] = i['user']['province']
       inf['location'] = i['user']['location']
       inf['关注'] = i['user']['friends_count']
       inf['fans'] = i['user']['followers_count']
       n=n+1
       collection.insert_one(inf)
       #print(inf)
   return max_id,n

total=0
max_id='0'
zero=15
while zero:
   url ='https://api.weibo.cn/2/comments/build_comments?flow=1&gsid=_2A2528V-DDeRxGeRM7loV9ifJyDuIHXVTp9RLrDV6PUJbkdAKLVf5kWpNU807bwxYkTUD9lwoQyaK4ajn_4FoWbka&wm=3333_2001&i=2a48abc&b=0&from=108B193010&c=iphone&networktype=wifi&v_p=69&skin=default&v_f=1&s=b1c8ec8f&lang=zh_CN&sflag=1&ua=iPhone9,1__weibo__8.11.1__iphone__os11.2.5&ft=11&aid=01AkR6c52cGZnAKXiIy1qC93kKA4LStXUv_uVymvDYrbPVZaw.&is_append_blogs=1&mid=4308928831894875&fid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&uicode=10000002&count=20&trim_level=1&moduleID=feed&max_id={}&is_show_bulletin=2&fetch_level=0&_status_id=4308928831894875&max_id_type=0&id=4308928831894875&luicode=10000003&featurecode=10000085&is_mix=1&page=0&lfid=100103type%3D1%26q%3D%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%26t%3D1&lcardid=seqid%3A870460522%7Ctype%3A1%7Ct%3A1%7Cpos%3A1-2-0%7Cq%3A%23%E5%A6%82%E6%9E%9C%E7%81%AB%E9%94%85%E5%8F%AA%E8%83%BD%E5%90%83%E4%B8%89%E6%A0%B7%E8%8F%9C%23%7Cext%3A%26cate%3D306%26mid%3D4308928831894875%26qtime%3D1542865414%26&rid=0_0_0_2669675512959047934_0_0&cum=6DD80FF3'.format(max_id)
   max = max_id
   try:
       max_id,num=get_inf(url)
   except Exception as e:
       print(e)
       time.sleep(30)
       max_id,num=get_inf(url)
   if not max_id:
       max_id=max
       zero=zero-1
       time.sleep(60)
   total=total+num
   time.sleep(random.randint(1,2))
   print(total)

有了数据我们就可以进行分析咯。。。

先来看看评论的男女比;评论的女生比男生多了不止一点点,完全不在一个量级上。女生差不多是男生的六倍!


下面来看看各时间段发表的评论数,昨天早上笔者醒来时刷了刷微博,大概早上九点,这条微博还在实时上升热点一栏;等笔者起来时大约10点半,这条微博已经冲进了热搜榜的前二十;等到下午三点左右,差不多在三十名;晚上大约十点半到宿舍,刷微博发现这个热搜仍然在三十名左右;这个排名的变化和下图是基本吻合的,所以大家不要老是说买热搜啦

有点好奇点赞数最多的是哪几条评论耶~下面这十一条是点赞数超过1000的评论,大家一起来品一品吧~

肉片拼盘,蔬菜拼盘,丸子拼盘 96985
毛肚 虾滑 肥牛[笑cry] 20752
肥牛土豆虾滑 8356
肥牛肥牛肥牛 6655
我自己给钱,火锅没有妥协[挖鼻] 6452
小孩子才选三个菜 大人要选三个拼盘!!!![doge] 6171
没有爱鸭肠脑花的么[泪] 4063
虾滑 肥牛 牛肚 2145
香菜 涮羊肉 牛百叶 1306
嫩牛肉、黄喉和虾滑[作揖] 1248
香菇、金针菇、鸡腿菇 1075

哈哈哈,第一条实在是太有才了,必须给个大大的赞👍。你说只让选三样,那我就选三个拼盘。下面来看看TOP3!

          

图左是单纯统计评论里各个单词出现的次数,图右将点赞数加进入,比如点赞数第一的评论:肉片拼盘,蔬菜拼盘和丸子拼盘,点赞数为96985,根据图左的算法,则算肉片拼盘,蔬菜拼盘和丸子拼盘出现一次,根据图右的算法,肉片拼盘,蔬菜拼盘和丸子拼盘出现次数为96985+1。图左的TOP3分别是肥牛,虾滑,毛肚;图右的TOP3分别是拼盘,蔬菜拼盘和丸子拼盘。广大网友真的非常机智噢~~~

上图是各省的评论数,四川果然是第一名,其次是江苏,北京,广东和山东。四川火锅不是吹的啊,全民火锅的节奏。来看看四川人最喜欢吃的TOP15吧。

土豆居然冲进了前三,虾滑变成了第四名。而毛肚变成了第一名,原来四川人最爱吃的是毛肚啊;如果给四川人点菜,一定记得点毛肚噢。

大家猜对TOP3了吗~~~

全部代码后续会上传到GitHub:https://github.com/zuobangbang/huoguo

Python爱好者社区历史文章大合集

Python爱好者社区历史文章列表(每周append更新一次)

福利:文末扫码立刻关注公众号,“Python爱好者社区”,开始学习Python课程:

关注后在公众号内回复“课程”即可获取:

小编的转行入职数据科学(数据分析挖掘/机器学习方向)【最新免费】

小编的Python入门免费视频课程!!!

小编的Python快速上手matplotlib可视化库!!!

崔老师爬虫实战案例免费学习视频。

陈老师数据分析报告制作免费学习视频。

玩转大数据分析!Spark2.X+Python 精华实战课程免费学习视频。


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存